from django.db import models

from django.contrib.contenttypes import generic
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType

#import itertools
from game_core import xunit

from buildings.models import BuildingType, Building

# Reference classes
class CellContentType(models.Model):
    """
    The type of cell content
    """
    name = models.CharField("User's custom name if is owned by anybody", max_length = 50, null = True)
    part = models.FloatField("The part in total cell count (0-100)", null = False)
    
    def __unicode__(self):
        return self.name
    
    @staticmethod
    def get_random_value():
        types = ()
        for type in CellContentType.objects.all():
            if type.part > 0 : types += ((type.part, type), )
        
        return xunit.select_weighted(types)

class AreaContentType(models.Model):
    """
    The type of area in the cell content
    """
    name = models.CharField(max_length = 50)
    child_count = models.IntegerField()

    def __unicode__(self):
        return self.name

class SlotType(models.Model):
    """
    The type of slot in the area content
    """
    name = models.CharField(max_length = 50)
    
    def __unicode__(self):
        return self.name

class SlotPlace(models.Model):
    """
    The place of slot in the area content
    """
    number = models.IntegerField()
    slot_type = models.ForeignKey(SlotType)
    area_content_type = models.ForeignKey(AreaContentType)
    
    def __unicode__(self):
        return "%d (%s, %s)" % (self.number, self.area_content_type, self.slot_type)

# Classes to create during game
class Map(models.Model):
    min_x = models.IntegerField(default = -100)
    min_y = models.IntegerField(default = -100)
    max_x = models.IntegerField(default = 100)
    max_y = models.IntegerField(default = 100)
    
    special_x = models.PositiveIntegerField(default = 0)
    special_y = models.PositiveIntegerField(default = 0)
    
    def __unicode__(self):
        return "Size X: %d, Size Y: %d" % (self.size_x, self.size_y)

    def rows_iterator():
        cells = list(Cell.objects.all(map = self).order_by('y', 'x'))
        for y in xrange(0, Map.size_y):
            yield itertools.islice(cells, y*Map.size_x, y*Map.size_x+Map.size_x)

class Cell(models.Model):
    """
    The map cell
    """
    x = models.IntegerField()
    y = models.IntegerField()
    owner = models.ForeignKey(User, blank=False, null=False)
    name = models.CharField(max_length = 100, null=True)
    map = models.ForeignKey(Map)

    # Reference to child content class
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content = generic.GenericForeignKey('content_type', 'object_id')

    def get_full_name(self):
        if self.name: full_name = self.name
        else: full_name = ""
        
        user = User.objects.get(id = self.owner.id)

        if not user.is_superuser: full_name += " of " + user.username

        return full_name

    def __unicode__(self):
        return "(%d, %d) %s" % (self.x, self.y, self.get_full_name())

class CellContent(models.Model):
    """
    The cell content
    """
    cell_content_type = models.ForeignKey(CellContentType)

    def __unicode__(self):
        return self.cell_content_type

class AreaContent(models.Model):
    """
    The area content
    """
    area_content_type = models.ForeignKey(AreaContentType)
    cell_content = models.ForeignKey(CellContent)
    
    def __unicode__(self):
        return " (%s)" % (self.area_content_type, )

class SlotContent(models.Model):
    """
    The content of area slot - place to buildings
    """
    slot_place = models.ForeignKey(SlotPlace)
    area_content = models.ForeignKey(AreaContent)

    # Reference to child content class
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content = generic.GenericForeignKey('content_type', 'object_id')

    def __unicode__(self):
        return "%s: %s" % (self.slot_place, self.content)

    @staticmethod
    def get_random_content(slot_place_id):
        return SlotContent(slot_place_id = slot_place_id, content = Building.get_random_content())
